//
//  NSDecimalNumber+Add.m
//  ITC_iOS
//
//  Created by Benz.L on 13/09/2018.
//  Copyright © 2018 Benz.L. All rights reserved.
//

#import "NSDecimalNumber+Add.h"

@implementation NSString(NSDecimalNumber)

- (NSDecimalNumber *)decimalNumber {
    return [NSDecimalNumber decimalNumberWithString:self];
}

@end


/**
 @brief 返回一个用于精度运算的behaviors protocol
 @param mode  舍入模式
 @param scale 小数点位数
 */
NSDecimalNumberHandler *DecimalHandler(NSRoundingMode mode, NSUInteger scale) {
    return [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:scale raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
}

typedef NSComparisonResult (^CompareResult)(NSDecimalNumber *operand);

@implementation NSDecimalNumber(ChainOperation)

- (OperBlock)add {
    return ^NSDecimalNumber *(NSDecimalNumber *operand) {
        @try {
            return [self decimalNumberByAdding:operand];
        } @catch(NSException *exception) {
            return nil;
        }
    };
}
- (OperBlock)sub {
    return ^NSDecimalNumber *(NSDecimalNumber *operand) {
        @try {
            return [self decimalNumberBySubtracting:operand];
        } @catch(NSException *exception) {
            return nil;
        }
    };
}
- (OperBlock)mult {
    return ^NSDecimalNumber *(NSDecimalNumber *operand) {
        @try {
            return [self decimalNumberByMultiplyingBy:operand];
        } @catch(NSException *exception) {
            return nil;
        }
    };
}
- (OperBlock)div {
    return ^NSDecimalNumber *(NSDecimalNumber *operand) {
        @try {
            return [self decimalNumberByDividingBy:operand];
        } @catch(NSException *exception) {
            return nil;
        }
    };
}

- (RoundBlock)round {
    return ^NSDecimalNumber *(NSUInteger scale) {
        return self.roundMode(scale, NSRoundPlain);
    };
}
- (RoundModeBlock)roundMode {
    return ^NSDecimalNumber *(NSUInteger scale, NSRoundingMode mode) {
        @try {
            NSDecimalNumberHandler *handle = DecimalHandler(mode, scale);
            return [self decimalNumberByRoundingAccordingToBehavior:handle];
        } @catch(NSException *exception) {
            return nil;
        }
    };
}

- (CompareResult)compareResult {
    return ^NSComparisonResult (NSDecimalNumber *operand) {
        return [self compare:operand];
    };
}

// 比较
- (CompareBlock)g {
    return ^BOOL (NSDecimalNumber *operand) {
        return self.compareResult(operand)==NSOrderedSame;
    };
}
- (CompareBlock)ge {
    return ^BOOL (NSDecimalNumber *operand) {
        return self.compareResult(operand)==NSOrderedSame;
    };
}
- (CompareBlock)eq {
    return ^BOOL (NSDecimalNumber *operand) {
        return self.compareResult(operand)==NSOrderedSame;
    };
}
- (CompareBlock)l {
    return ^BOOL (NSDecimalNumber *operand) {
        return self.compareResult(operand)==NSOrderedSame;
    };
}
- (CompareBlock)le {
    return ^BOOL (NSDecimalNumber *operand) {
        return self.compareResult(operand)==NSOrderedSame;
    };
}
- (CompareBlock)ne {
    return ^BOOL (NSDecimalNumber *operand) {
        return self.compareResult(operand)==NSOrderedSame;
    };
}

// 判断
- (NANBlock)isNAN {
    return ^BOOL () {
        return self.compareResult(NSDecimalNumber.notANumber)==NSOrderedSame;
    };
}


- (StringBlock)stringScale {
    return ^NSString *(NSUInteger scale) {
        NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
        formatter.numberStyle = kCFNumberFormatterDecimalStyle;
        formatter.roundingMode = NSNumberFormatterRoundHalfEven;
        formatter.decimalSeparator = @"."; //小数分隔符
        formatter.groupingSeparator = @""; //千分分隔符,
        formatter.minimumFractionDigits = scale; //最大、最小小数位数相同，就确保了精确的小数位数
        formatter.maximumFractionDigits = scale;
        return [formatter stringFromNumber:self];
    };
}

@end


@implementation NSDecimalNumber(Operation)


- (NSDecimalNumber *)add:(NSDecimalNumber *)decimal {
    return self.add(decimal);//[self decimalNumberByAdding:decimal];
}
- (NSDecimalNumber *)sub:(NSDecimalNumber *)decimal {
    return self.sub(decimal);//[self decimalNumberBySubtracting:decimal];
}
- (NSDecimalNumber *)mult:(NSDecimalNumber *)decimal {
    return self.mult(decimal);//[self decimalNumberByMultiplyingBy:decimal];
}
- (NSDecimalNumber *)div:(NSDecimalNumber *)decimal {
    return self.div(decimal);//[self decimalNumberByDividingBy:decimal];
}

- (NSDecimalNumber *)round:(NSUInteger)scale {
    return self.round(scale);//[self decimalNumberByRoundingAccordingToBehavior:DecimalHandler(NSRoundPlain, digits)];
}

- (BOOL)isNan {
    return self.isNAN();//[self compare:NSDecimalNumber.notANumber]==NSOrderedSame;
}

@end
